<template>
  <div v-loading="loading">
    <template v-if="styleType == 's1'">
      <div class="w-full mt-2">
        <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
      </div>
      <p>{{ modelValueLabel }}</p>
      <el-select v-model="modelValueLabel" :collapse-tags="true" multiple :placeholder="placeholderText" :size="size" @visible-change="selectClose">
        <el-option style="height: auto; padding: 0" :value="modelValue">
          <el-tree
            ref="selectTree"
            :check-strictly="true"
            :current-node-key="currentNodeKey"
            :data="data"
            :default-checked-keys="checkedKeys"
            :default-expand-all="defaultExpandAll"
            :expand-on-click-node="expandOnClickNode"
            :filter-node-method="filterNode"
            :highlight-current="true"
            :node-key="nodeKey"
            :props="defaultProps"
            :show-checkbox="showCheckbox"
            @check="handleCheck"
            @check-change="handleCheckChange"
            @node-click="handleNodeClick"
          />
        </el-option>
      </el-select>
    </template>
    <template v-if="styleType == 's2'">
      <div class="w-full mt-2">
        <el-input v-model="filterText" placeholder="输入关键字进行过滤" />
      </div>
      <p>{{ modelValueLabel }}</p>
      <div class="border border-gray-200 mt-1 rounded-sm">
        <el-scrollbar :height="height - 40 + 'px'">
          <Ztree ref="selectTree" :nodes="data" :setting="setting" @onCheck="onCheck" @onClick="onClick" @onCreated="onCreated" />
        </el-scrollbar>
      </div>
    </template>
  </div>
</template>

<script>
  import { defineComponent } from 'vue'
  import Ztree from './ztree'
  import cloneDeep from 'lodash/cloneDeep'
  export default defineComponent({
    name: 'VuiTreeSelectZtree',
    components: {
      Ztree,
    },
    props: {
      // 加载中
      loading: {
        type: Boolean,
        default: false,
      },
      // 区分来源
      name: {
        type: String,
        default: '',
      },
      // 是否默认展开所有节点
      defaultExpandAll: {
        type: Boolean,
        default: true,
      },
      //是否多选
      hasCheckbox: {
        type: Boolean,
        default: false,
      },
      //显示多选
      showCheckbox: {
        type: Boolean,
        default: true,
      },
      //是否在点击节点的时候展开或者收缩节点
      expandOnClickNode: {
        type: Boolean,
        default: true,
      },
      // 直接绑定
      // returnData: {
      //   type: Object,
      //   default: function () {
      //     return {}
      //   },
      // },
      // 样式类型
      styleType: {
        type: String,
        default: 's2', //s1默认 s2直接显示tree
      },
      // 尺寸
      height: {
        type: String,
        default: '300',
      },
      // 大小
      size: {
        type: String,
        default: 'mini',
      },
      placeholderText: {
        type: String,
        default: '请选择...',
      },
      // 字段key， 数据中的id
      nodeKey: {
        type: String,
        default: 'id',
      },
      // 数据
      data: {
        type: Array,
        default: function () {
          return []
        },
      },
      // 回填数据
      checkedKeys: {
        type: Array,
        default: function () {
          return []
        },
      },
      // 当前选中的节点
      currentNodeKey: {
        type: String,
        default: function () {
          return ''
        },
      },
      // 遍历时字段格式化
      defaultProps: {
        type: Object,
        default: function () {
          return {}
        },
      },
    },
    emits: ['checkedChange', 'nodeClick', 'update:modelValue'],
    data() {
      return {
        // 实际选中值
        modelValue: [],
        // 下拉框绑定值(选中值名字)
        modelValueLabel: [],

        // multiples: [], // 多选缓存数据
        filterText: '',
        treeObj: null, //treeobj
        setting: {
          check: {
            enable: this.showCheckbox,
            chkStyle: 'checkbox',
            chkboxType: { Y: '', N: '' },
          },
          data: {
            simpleData: {
              enable: true,
              idKey: '_id',
            },
            key: {
              children: 'list',
            },
            render: {
              name: function (name) {
                return `${name}`
              },
            },
          },
        },
        listData: undefined,
        nodeList: [],
        //选中数据
        checkdata: {
          checkedKeys: [],
          checkedNodes: [],
          halfCheckedKeys: [],
          halfCheckedNodes: [],
        },
      }
    },
    computed: {},
    watch: {
      filterText(val) {
        //this.$refs['selectTree'].filter(val)
        if (!this.treeObj) return
        this.searchNode(val, 'name')
      },
    },
    created() {
      //合并参数
      this.extendPrimes(this.setting, this.defaultProps)
      //处理数据
      this.listData = cloneDeep(this.data || [])
      this.filterTreeData(this.listData)
    },
    mounted() {
      // this.$nextTick(() => {
      //   this.loadMultiples()
      // })
    },
    methods: {
      selectClose(bool) {
        console.log('selectClose', bool)
      },
      handleNodeClick(item) {
        this.$emit('nodeClick', item)
      },
      handleCheckChange(data, checked) {
        //单选处理
        if (checked) {
          if (!this.hasCheckbox) {
            this.$refs.selectTree.setCheckedKeys([data._id])
          }
        }
      },
      handleCheck(nodes, data) {
        // this.multiples = data.checkedNodes
        let labels = []
        data.checkedNodes.forEach((v) => {
          labels.push(v[this.defaultProps.label])
        })
        this.modelValue = data.checkedKeys
        this.modelValueLabel = labels
        // emit
        this.$emit('checkedChange', {
          multiples: data.checkedNodes,
          keys: data.checkedKeys,
          name: this.name,
        })
        this.$emit('update:modelValue', data.checkedKeys)
      },
      //过滤节点
      filterNode(value, data) {
        if (!value) return true
        return data.name.indexOf(value) !== -1
      },
      //初始化完成执行
      onCreated(ztreeObj) {
        //赋值treeobj
        this.treeObj = ztreeObj
        //展开事件 default-expand-all
        ztreeObj.expandAll(this.defaultExpandAll)
        //选中的公共逻辑
        function selectItems(nodes = [], ztreeObj, callback) {
          const nodesLength = ztreeObj.transformToArray(ztreeObj.getNodes())
          for (var i = 0, l = nodes.length; i < l; i++) {
            const find = nodesLength.find((item) => item._id === nodes[i])
            if (find) {
              callback && callback.call(this, find)
              break
            }
          }
        }
        //如果存在回填数据
        if (this.checkedKeys.length) {
          //选中数据 default-checked-keys
          selectItems(this.checkedKeys, ztreeObj, function (find) {
            //checkbox勾选
            ztreeObj.checkNode(find, true, true)
            ztreeObj.selectNode(find, true)
          })
        }
        //当前选中的节点 currentNodeKey
        if (this.currentNodeKey) {
          const selectItems = this.currentNodeKey.split(',')
          //选中当前节点
          selectItems(selectItems, ztreeObj, function (find) {
            //选中当前节点
            ztreeObj.selectNode(find, true)
          })
        }
        //隐藏特定条件的组件:filter-node-method
        // const allNode = ztreeObj.transformToArray(ztreeObj.getNodes()) || []
        // for (let i = 0; i < allNode.length; i++) {
        //   //隐藏特定条件的组件:filter-node-method
        //   allNode[i].isHidden = !this.filterNode(allNode.name, allNode[i])
        //   //没有子集本身就是子集
        //   if (allNode[i].list && !allNode[i].list.length) {
        //     allNode[i].isParent = false
        //     allNode[i].open = false
        //   }
        //   ztreeObj.updateNode(allNode[i])
        // }
      },
      //选中
      onCheck(event, treeId, treeNode) {
        //单选设置
        if (treeNode.checked) {
          this.treeObj.checkAllNodes(false)
          this.treeObj.checkNode(treeNode, true, true)
          this.checkdata.checkedKeys[0] = treeNode[this.nodeKey]
          this.checkdata.checkedNodes[0] = treeNode
        } else {
          this.checkdata.checkedKeys = []
          this.checkdata.checkedNodes = []
        }
        //沿用以前逻辑
        this.handleCheck(treeNode, this.checkdata)
      },
      //点击
      onClick(event, treeId, treeNode) {
        //点击展开操作 expand-on-click-node
        if (this.expandOnClickNode && treeNode.isParent) {
          this.treeObj.expandNode(treeNode, !treeNode.open, true, true)
        }
        //点击触发
        this.handleNodeClick.call(this, treeNode)
      },
      //搜索树形数据
      searchNode(value, name) {
        const keyType = name
        if (value === '') {
          this.treeObj.cancelSelectedNode()
          const allNode = this.treeObj.transformToArray(this.treeObj.getNodes())
          this.treeObj.showNodes(allNode)
          this.treeObj.expandAll(true)
          return
        }
        //过滤
        this.nodeList = this.treeObj.getNodesByParamFuzzy(keyType, value)
        //转换成数组
        this.nodeList = this.treeObj.transformToArray(this.nodeList)
        this.updateNodes(true, value, keyType)
      },
      //更新树形节点
      updateNodes(highlight, value, keyType) {
        const allNode = this.treeObj.transformToArray(this.treeObj.getNodes())
        this.treeObj.hideNodes(allNode)
        for (let n in this.nodeList) {
          this.findParent(this.treeObj, this.nodeList[n])
        }
        this.treeObj.showNodes(this.nodeList)
        this.closeAll()
        this.nodeList = this.treeObj.getNodesByParamFuzzy(keyType, value)
        for (let i = 0; i < this.nodeList.length; i++) {
          //zTree.updateNode(nodes[i]);
          this.treeObj.selectNode(this.nodeList[i], true)
        }
      },
      //找父级
      findParent(zTree, node) {
        zTree.expandNode(node, true, false, false)
        const pNode = node.getParentNode()
        if (pNode != null) {
          this.nodeList.push(pNode)
          this.findParent(zTree, pNode)
        }
      },
      closeAll() {
        this.treeObj.expandAll(false) //关闭所有节点
        const nodes = this.treeObj.getNodes()
        for (let i = 0; i < nodes.length; i++) {
          this.treeObj.expandNode(nodes[i], true, false, true) //打开根节点
        }
      },
      //合并参数
      extendPrimes(target, source) {
        for (let key in source) {
          if (toString.call(source[key]) === '[object Object]') {
            target[key] = target[key] || {}
            this.extendPrimes(target[key], source[key])
          } else {
            target[key] = source[key]
          }
        }
      },
      //处理传入的数据
      filterTreeData(data) {
        if (Array.isArray(data)) {
          const $this = this
          data.forEach((item) => {
            $this.filterTreeData(item)
          })
          return
        }
        if (!data.list) {
          return
        }
        if (!data.list.length) {
          delete data.list
        } else {
          this.filterTreeData(data.list)
        }
      },
    },
  })
</script>

<style lang="scss" scoped>
  // :deep() {
  //   .el-tree-node.is-current > .el-tree-node__content {
  //     background: #999;
  //   }
  // }
</style>
